/**
 * @file gjson_data.c
 * @brief json data operation
 * @author JakeYang <add358@gmail.com>
 * @version 0.1
 * @date 2016-03-01
 */

#include <gjson_data.h>

struct _GJsonData {
    gchar *data;
};

inline GJsonData *g_json_data_new(gchar *data)
{
    GJsonData *d = g_malloc0(sizeof(GJsonData));
    d->data = data;
    return d;
}

void g_json_data_free(GJsonData *d, gboolean free_segment)
{
    if (free_segment) {
        g_free(d->data);
    }
    g_free(d);
}

void g_json_data_skip(GJsonData *d)
{
    while (*(d->data)) {
        if ((guchar)(*(d->data)) <= 32) {
            /* skip space */
            for (; *(d->data) && (guchar)(*(d->data)) <= 32; ++(d->data)) {}
        } else if (*(d->data) == '/' && *(d->data+1) == '/') {
            /* skip note */
            for (d->data += 2; *(d->data) && '\n' != *(d->data); ++(d->data)) {}
            if (*(d->data)) {
                ++(d->data);
            }
        } else if (*(d->data) == '/' && *(d->data+1) == '*' ) {
            /* skip note */
            for (d->data += 2; *(d->data) && ('*' != *(d->data) || '/' != *(d->data+1)); ++(d->data)) {}
            if (*(d->data)) {
                d->data += 2;
            }
        } else {
            break;
        }
    }
}

inline gchar g_json_data_char(const GJsonData *d)
{
    if (NULL == d) {
        return '\0';
    }
    return *(d->data);
}

inline void g_json_data_forward(GJsonData *d, gint offset)
{
    d->data += offset;
}

gchar *g_json_data_get_str(GJsonData *d)
{
    gchar *s = NULL;
    gchar *e = NULL;

    s = d->data;
    if ('\"' != *s) {
        return NULL;
    }

    for (e=s+1; *e && ( '\"' != *e); ++e) {}

    if (e-s-1 > GJSON_KEY_MAX || '\0' == *e) {
        return NULL;
    } else {
        d->data = e+1;
        return g_strndup(s+1, e-s-1);
    }
}

inline gboolean g_json_data_equal_char(const GJsonData *d, gchar c)
{
    return (*(d->data) == c);
}

gboolean g_json_data_equal_str(const GJsonData *d, const gchar *str, gint n)
{
    const gchar *s1 = d->data;
    while (n--) {
        if ((*s1-*str) || ('\0'== *s1 || '\0' == *str)){
            break;
        }
        ++s1;
        ++str;
    }
    return !(*(s1-1)-*(str-1));
}

gchar *g_json_data_get_number(GJsonData *d)
{
    gboolean isFloat = FALSE;
    gboolean isExponent = FALSE;

    gchar *s = d->data;
    gchar *e = s;

    if ('-' == *e) {
        ++e;
    }

    while (*e++) {
        if (('0' <= *e) && ('9' >= *e)) {
        } else if ( ('e' == *e) && !isExponent) {
            isExponent = TRUE;
        } else if (('.' == *e) && !isFloat) {
            isFloat = TRUE;
        } else {
            break;
        }
    }

    d->data = e;

    return g_strndup(s, e-s);
}
